﻿using System;
using System.Collections;
using System.IO;
using System.Xml.Serialization;

namespace Core.Config
{
    public static class AccessXmlSerializer
    {
        public static readonly object LockObject = new object();
        private static Hashtable serializers = new Hashtable();
        private static XmlSerializer xs;

        /// <summary>
        /// 将对象反序列化为指定XML文件
        /// </summary>
        /// <param name="filePath">路径</param>
        /// <param name="sourceObj">对象</param>
        /// <returns>是否成功</returns>
        public static bool ObjectToXml(string filePath, object sourceObj)
        {
            lock (LockObject)
            {
                if (!string.IsNullOrWhiteSpace(filePath) && sourceObj != null)
                {
                    string folderPath = filePath.Substring(0, filePath.LastIndexOf(@"\"));
                    if (Directory.Exists(folderPath) == false)
                    {
                        Directory.CreateDirectory(folderPath);
                    }
                    try
                    {
                        using (StreamWriter writer = new StreamWriter(filePath))
                        {
                            CreateXMLSerial(sourceObj.GetType()).Serialize(writer, sourceObj);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message, ex);            
                    }
                }
                else
                {
                    //NotifyG.Error("将对象反序列化为指定XML文件失败:路径或对象是否为空");
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 将指定XML反序列化为对象
        /// </summary>
        /// <param name="filePath">XML路径</param>
        /// <param name="type">类型</param>
        /// <returns>object</returns>
        public static object XmlToObject(string filePath, Type type)
        {
            object result = null;
            lock (LockObject)
            {
                if (File.Exists(filePath))
                {
                    try
                    {
                        using (StreamReader reader = new StreamReader(filePath))
                        {
                            result = CreateXMLSerial(type).Deserialize(reader);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(ex.Message, ex);
                    }
                }
                else
                {
                    //NotifyG.Add("将指定XML反序列化为对象失败:" + filePath + "路径不存在");
                }
                return result;
            }
        }

        /// <summary>
        /// 将指定XML反序列化为对象
        /// </summary>
        /// <typeparam name="T">对象</typeparam>
        /// <param name="filePath">路径</param>
        /// <returns>对象</returns>
        public static T XmlToObject<T>(string filePath)
        {
            return (T)XmlToObject(filePath, typeof(T));
        }

        private static XmlSerializer CreateXMLSerial(Type type)
        {
            object key = type.Name;
            xs = (XmlSerializer)serializers[key];
            if (xs == null)
            {
                xs = string.IsNullOrWhiteSpace(type.Name) ? new XmlSerializer(type) :
                            new XmlSerializer(type, new XmlRootAttribute(type.Name));
                serializers[key] = xs;
            }
            return xs;
        }
    }
}
